package cheme.ProcessEditor.Policies;

import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.geometry.Transposer;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.editpolicies.FlowLayoutEditPolicy;
import org.eclipse.gef.requests.DropRequest;

public abstract class ToolbarLayoutEditPolicy extends FlowLayoutEditPolicy
{
	/**
	 * @return <code>true</code> if the host's LayoutManager is in a horizontal orientation
	 */
	@Override
	protected boolean isHorizontal()
	{
		IFigure figure = ((GraphicalEditPart)getHost()).getContentPane();
		return ((ToolbarLayout)figure.getLayoutManager()).isHorizontal();
	}
	
	protected Point getLocationFromRequest(Request request)
	{
		return ((DropRequest)request).getLocation();
	}
	
	protected Rectangle getAbsoluteBounds(GraphicalEditPart ep)
	{
		Rectangle bounds = ep.getFigure().getBounds().getCopy();
		ep.getFigure().translateToAbsolute(bounds);
		return bounds;
	}
	
	/**
	 * @param request the Request
	 * @return the index for the insertion reference
	 */
	protected int getFeedbackIndexFor(Request request)
	{
		List children = getHost().getChildren();
		
		if(children.isEmpty())
		{
			return -1;
		}

		Transposer transposer = new Transposer();
		transposer.setEnabled(!isHorizontal());

		Point p = transposer.t(getLocationFromRequest(request));

		// Current row bottom, initialize to above the top.
		int rowBottom = Integer.MIN_VALUE;
		int candidate = -1;
		for(int i = 0; i < children.size(); i++)
		{
			EditPart child = (EditPart)children.get(i);
			Rectangle rect = transposer.t(getAbsoluteBounds(((GraphicalEditPart)child)));
			
			if(rect.y > rowBottom)
			{
				/*
				 * We are in a new row, so if we don't have a candidate but yet
				 * are within the previous row, then the current entry becomes
				 * the candidate. This is because we know we must be to the
				 * right of center of the last Figure in the previous row, so
				 * this Figure (which is at the start of a new row) is the
				 * candidate.
				 */
				if(p.y <= rowBottom)
				{
					if(candidate == -1)
					{
						candidate = i;
					}
					break;
				}
				else
				{
					candidate = -1; // Mouse's Y is outside the row, so reset the candidate
				}
			}
			
			rowBottom = Math.max(rowBottom, rect.bottom());
			if(candidate == -1)
			{
				/*
				 * See if we have a possible candidate. It is a candidate if the
				 * cursor is left of the center of this candidate.
				 */
				if(p.x <= rect.x + (rect.width / 2))
				{
					candidate = i;
				}
			}
			if(candidate != -1)
			{
				// We have a candidate, see if the rowBottom has grown to
				// include the mouse Y.
				if(p.y <= rowBottom)
				{
					/*
					 * Now we have determined that the cursor.Y is above the
					 * bottom of the current row of figures. Stop now, to
					 * prevent the next row from being searched
					 */
					break;
				}
			}
		}
		return candidate;
	}
}
